import { CodeGenerate, CodeGenerateField, FieldTypeInterfaceMap } from "@/types/admin/codeGenerate";
import lodash from "lodash";

export const getAdminTypeCode = (data: Omit<CodeGenerate, "fields"> & { fields: CodeGenerateField[] }) => {
    const { fields, modelName, lookupList } = data;
    return `import { TimeStamp } from ".";
${fields.some(item=>FieldTypeInterfaceMap[item.type] === 'ObjectId')?'import { ObjectId } from "mongoose";\n\n':''}export interface ${modelName} extends TimeStamp {
    _id: string;
    ${(fields as CodeGenerateField[]).map(item => `${item.name}${item.required ? ":" : "?:"} ${FieldTypeInterfaceMap[item.type]}`).join(";\n\t")}${
        fields?.length ? ";" : ""
    }
}

export type Create${modelName}Req = Omit<${modelName},${lookupList?.map(item => `"${item.localField}"`).join(" | ")}${
        lookupList?.length ? " | " : ""
    }"_id" | keyof TimeStamp> & {
    ${lookupList?.map(item => `${item.localField}?: any`).join(";\n\t")}${lookupList?.length ? ";" : ""}
};

export interface Update${modelName}Req extends Omit<Partial<${modelName}>, ${lookupList?.map(item => `"${item.localField}"`).join(" | ")}${
        lookupList?.length ? " | " : ""
    }keyof TimeStamp> {
    _id: string;
    ${lookupList?.map(item => `${item.localField}?: any`).join(";\n\t")}${lookupList?.length ? ";" : ""}
}`;
};

export const getAdminApiCode = (data: Omit<CodeGenerate, "fields"> & { fields: CodeGenerateField[] }) => {
    const { modelName } = data;
    return `import { PageReq } from "@/typings/api";
import { ${modelName}, Create${modelName}Req, Update${modelName}Req } from "@/typings/api/${lodash.lowerFirst(modelName)}";
import { request } from "@/utils/request";

export const get${modelName}List = (params: PageReq<${modelName}>) => request.get("/${lodash.lowerFirst(modelName)}", { params });
export const get${modelName}Record = (_id: string) => request.get(\`/${lodash.lowerFirst(modelName)}/\${_id}\`);
export const create${modelName} = (data: Create${modelName}Req) => request.post("/${lodash.lowerFirst(modelName)}", data);
export const update${modelName} = (data: Update${modelName}Req) => request.put("/${lodash.lowerFirst(modelName)}", data);
export const delete${modelName} = (_id: string) => request.delete("/${lodash.lowerFirst(modelName)}", { data: { _id } });`;
};

export const getAdminListPageCode = (data: Omit<CodeGenerate, "fields"> & { fields: CodeGenerateField[] }) => {
    const { modelName, fields, pageName, permissionKey } = data;
    return `import { create${modelName}, delete${modelName}, get${modelName}List, update${modelName} } from "@/api/${lodash.lowerFirst(modelName)}";
import { formatFormItem, FormItemType, FormTableItemType } from "@/components/FormByData/FormByData";
import Table, { TableRef } from "@/components/Table";
import { Card, Space, Button, message, FormInstance } from "antd";
import { MutableRefObject, useRef, useState } from "react";
import { Operation } from "@/typings/common";
import { formatDate } from "@/utils/date";
import { EditOutlined } from "@ant-design/icons";
import FormByData from "@/components/FormByData/FormByData";
import { Create${modelName}Req, ${modelName} as ${modelName}Type, Update${modelName}Req } from "@/typings/api/${lodash.lowerFirst(modelName)}";
import Search from "@/components/Search";
import Modal from "@/components/Modal/Modal";
import DictionaryColumnRender from "@/components/DictionaryColumnRender";

type SearchFields = Pick<${modelName}Type, ${(fields as CodeGenerateField[])
        .filter(item => item.queryType)
        .map(item => `"${item.name}"`)
        .join(" | ")}>;

const ${modelName} = () => {
    const columns: FormTableItemType<Update${modelName}Req>[] = [
        ${(fields as CodeGenerateField[])
            .map(
                item =>
                    `{ dataIndex: "${item.name}", title: "${item.label}"${
                        item.dictType
                            ? `, dictType: "${
                                  item.dictType
                              }", dictClass: "${item.type.toLocaleLowerCase()}", render: value => <DictionaryColumnRender dictType="${
                                  item.dictType
                              }" value={value} />`
                            : ""
                    }${!item.isForm ? ", isForm: false" : ""}${!item.isTable ? ", isTable: false" : ""}${
                        item.componentType ? `, type: "${item.componentType}"` : ""
                    }${item.required ? `, required: ${item.required}` : ""}}`
            )
            .join(",\n\t\t")}${fields.length ? "," : ""}
        { dataIndex: "createdAt", title: "创建时间", render: val => formatDate(val), isForm: false },
        { dataIndex: "updatedAt", title: "更新时间", render: val => formatDate(val), isForm: false },
        { dataIndex: "operation", isForm: false, title: "操作", fixed: "right" },
    ];

    const [modalShow, setModalShow] = useState(false);
    const [opType, setOpType] = useState<Operation>("add");
    const currentRecord = useRef<Update${modelName}Req>();

    const handleAdd = () => {
        setOpType("add");
        setModalShow(true);
        formRef.current?.resetFields();
    };

    const clickEdit = (record: Update${modelName}Req) => {
        setOpType("edit");
        setModalShow(true);
        formRef.current?.resetFields();
        setTimeout(() => {
            formRef.current?.setFieldsValue(record);
        });
        currentRecord.current = record;
    };

    const tableRef = useRef<TableRef>(null);
    const formRef: MutableRefObject<FormInstance<Update${modelName}Req> | null> = useRef(null);
    const submit = async () => {
        const formData = await formRef.current?.validateFields?.();
        if (!formData) return;
        if (opType === "add") {
            await create${modelName}(formData as Create${modelName}Req);
            message.success("创建成功");
        } else {
            if (!currentRecord.current) return;
            await update${modelName}({ ...formData, _id: currentRecord.current._id });
            message.success("编辑成功");
        }
        tableRef.current?.getList();
        setModalShow(false);
    };

    const searchFormItems: FormItemType[] = [
        ${(fields as CodeGenerateField[])
            .filter(item => item.queryType)
            .map(item => `{ label: "${item.label}", name: "${item.name}" }`)
            .join(",\n\t\t")}${fields.length ? "," : ""}
    ];
    const searchParams = useRef<Partial<${modelName}Type>>({});
    const handleSearch = async (formData: SearchFields) => {
        searchParams.current = formData;
        await tableRef.current?.getList(1, 10);
    };

    const searchFromRef = useRef<FormInstance>();
    const handleReset = () => {
        searchFromRef.current?.resetFields();
        searchParams.current = {};
        tableRef.current?.getList(1, 10);
    };
    return (
        <Card
            title={
                <Search<SearchFields>
                    title="${pageName}"
                    formItems={searchFormItems}
                    onReset={handleReset}
                    onAdd={handleAdd}
                    onSearch={handleSearch}
                    getFormRef={ref => (searchFromRef.current = ref)}${
                        permissionKey
                            ? `\n\t\t\t\t\tcreatePermission="${permissionKey}/create"\n\t\t\t\t\tlistPermission="${permissionKey}/list"`
                            : ""
                    }
                />
            }
        >
            <Table<Update${modelName}Req>
                ref={tableRef}
                columns={columns}
                getApi={p => get${modelName}List({ ...p, ...searchParams.current })}
                delApi={delete${modelName}}
                actionMore={record => (
                    <Space>
                        <Button type="primary" size="small" icon={<EditOutlined />} onClick={() => clickEdit(record)}>
                            编辑
                        </Button>
                    </Space>
                )}${
                    permissionKey
                        ? `\n\t\t\t\tupdatePermission="${permissionKey}/update"\n\t\t\t\tdeletePermission="${permissionKey}/delete"`
                        : ""
                }
            />

            <Modal
                title={opType === "add" ? "添加" : "编辑"}
                open={modalShow}
                onCancel={() => setModalShow(false)}
                onOk={submit}
                forceRender
            >
                <FormByData
                    getFormRef={ref => (formRef.current = ref)}
                    formItems={formatFormItem(columns)}
                    cols={1}${fields.some(item => item.name === "status") ? "\n\t\t\t\t\tformProps={{ initialValues: { status: true } }}" : ""}
                />
            </Modal>
        </Card>
    );
};

export default ${modelName};`;
};
